// Package global 全局变量和初始化函数包
// 提供全局数据库连接对象和连接初始化方法
// 在应用程序启动时初始化，并在需要访问数据库的地方使用全局DB变量
package global

import (
	// fmt 包：提供格式化I/O功能，用于输出错误信息和调试信息
	"fmt"
	// models 包：包含应用程序的数据模型定义
	"gin-gorm/models"
	// log 包：提供日志记录功能，用于记录严重错误
	"log"
	// strings 包：提供字符串处理功能，用于表名替换

	// mysql 包：GORM的MySQL驱动，用于连接MySQL数据库
	"gorm.io/driver/mysql"
	// gorm 包：Go语言的ORM库，提供数据库操作的高级抽象
	"gorm.io/gorm"
	// schema 包：GORM的模式定义，用于配置表名生成策略等
	"gorm.io/gorm/schema"
)

// DB 全局数据库连接对象，在整个应用程序中使用
// 所有需要访问数据库的地方都可以直接使用这个全局变量
// 在Connect函数调用成功后初始化，确保在使用前完成初始化
var DB *gorm.DB

// Connect 初始化数据库连接
// 连接到本地MySQL数据库并设置全局DB变量
// 在应用程序启动时调用此函数来初始化数据库连接
// 通常在main函数的开始位置调用，确保数据库连接在使用前已建立
// 无参数，无返回值，但会设置全局变量DB和在连接失败时打印错误信息
func Connect() {
	// 数据库连接字符串(DSN) - Data Source Name
	// 格式：username:password@tcp(host:port)/database?charset=utf8mb4&parseTime=True
	// 生产环境中建议从配置文件或环境变量中读取
	dsn := "root:root@tcp(127.0.0.1:3306)/gorm?charset=utf8mb4&parseTime=True"
	// 参数说明：
	// - root:root: MySQL用户名和密码
	// - tcp(127.0.0.1:3306): 使用TCP连接到本地MySQL服务器，端口3306
	// - /gorm: 使用名为gorm的数据库
	// - charset=utf8mb4: 设置字符集为utf8mb4，支持表情符号等特殊字符
	// - parseTime=True: 自动将MySQL的datetime等时间类型转换为Go的time.Time类型

	// 建立数据库连接
	// 使用gorm.Open函数打开数据库连接
	// mysql.Open(dsn)指定使用MySQL驱动并传入连接字符串
	// &gorm.Config{}传入GORM的配置选项
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
		// DisableForeignKeyConstraintWhenMigrating: true - 迁移时禁用外键约束
		// 这在开发阶段可以避免因表依赖关系导致的迁移失败
		DisableForeignKeyConstraintWhenMigrating: true, //禁止实体关联外键
		// NamingStrategy: 配置表名生成策略
		NamingStrategy: schema.NamingStrategy{
			// TablePrefix:   "t_", // 表名前缀，所有通过GORM创建的表都会添加此前缀
			// SingularTable: true, // 使用单数表名，例如UserModel会映射到t_UserModel而不是t_user_models
			// NoLowerCase:   true, // 关闭蛇形命名，保持表名的驼峰命名风格
			// NameReplacer: 自定义名称替换规则，这里将CID替换为Cid
			// NameReplacer:  strings.NewReplacer("CID", "Cid"),
		},
	})

	// 错误处理
	if err != nil {
		// 如果连接失败，打印错误信息
		// 在实际生产环境中，可能需要记录到日志系统并考虑重试机制
		fmt.Println("数据库连接失败:", err)
		return
	}

	// 设置全局数据库连接对象
	// 成功连接后，将连接对象赋值给全局变量DB
	// 其他模块可以通过global.DB直接访问数据库连接
	DB = db
}

// Migrate 执行数据库迁移操作
// 使用GORM的AutoMigrate功能自动创建或更新数据表结构
// 根据注册的模型结构自动同步数据库表结构
// 无参数，无返回值，但在迁移失败时会记录致命错误并终止程序
func Migrate() {
	// 调用DB.AutoMigrate方法执行数据库迁移
	// 传入所有需要迁移的数据模型结构体指针
	err := DB.AutoMigrate(
		&models.UserModel{},         // 用户模型
		&models.UserDetailModel{},   // 用户详情模型
		&models.GirlModel{},         // 女孩模型
		&models.BoyModel{},          // 男孩模型
		&models.ArticleModel{},      // 文章模型
		&models.TagModel{},          // 标签模型
		&models.User1Model{},        // 用户模型（另一版本）
		&models.Article1Model{},     // 文章模型（另一版本）
		&models.User2ArticleModel{}, // 用户-文章多对多关联模型
		&models.UserZdy{},           // 自定义数据类型用户模型
		&models.LogModel{},          // 日志模型（带枚举类型）
	)
	// 错误处理
	if err != nil {
		// 如果迁移失败，记录致命错误并终止程序
		// Fatalf会在输出错误信息后调用os.Exit(1)
		log.Fatalf("数据库迁移失败 %v", err)
	}
	// 迁移成功后打印成功信息
	fmt.Println("数据库迁移成功")
}
